﻿using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using netduino.helpers.Hardware;

namespace AdaFruitOLED {
    public class CropCircleLocation {
        public int x { get; set; }
        public int y { get; set; }
        private int _speedX;
        private int _speedY;
        private int _direction;
        public CropCircleLocation(Random rand, int maxX, int maxY) {
            x = rand.Next(maxX);
            y = rand.Next(maxY);
            _speedX = rand.Next(5) + 1;
            _speedY = rand.Next(5) + 1;
            _direction = rand.Next(2);
            if (_direction == 0) {
                _direction = -1;
            }
        }

        public void Move(int maxX, int maxY) {
            x += (_speedX * _direction);
            if (x < 0) {
                x = maxX - 1;
            } else if (x > maxX) {
                x = 0;
            }

            y += (_speedY * _direction);
            if (y < 0) {
                y = maxY - 1;
            } else if (y >= maxY) {
                y = 0;
            }
        }
    }

    public class Program {
        public static AdaFruitSSD1306 oled = new AdaFruitSSD1306(
            chipSelect: Pins.GPIO_PIN_D10,
            reset: Pins.GPIO_PIN_D9,
            dc: Pins.GPIO_PIN_D8,
            speedKHz: 40000);

        public static void Main() {                        
            oled.Initialize();

            while (true) {
                DisplayNetduinoBitmap();
                BlinkTest();
                DisplayText();
                DisplayLines();
                DisplayCircles();
                DisplaySquares();
                DisplaySpaceInvaders();
            }
        }

        public static void DisplaySpaceInvaders() {
            var random = new Random((int)DateTime.Now.Ticks);
            var cropCircles = new ArrayList();
            var maxSpaceInvaders = 5;
            for (var count = 0; count < maxSpaceInvaders; count++) {
                cropCircles.Add(new CropCircleLocation(random, AdaFruitSSD1306.Width, AdaFruitSSD1306.Height));
            }

            while (true) {
                oled.ClearScreen(); 
                foreach (CropCircleLocation loc in cropCircles) {
                    loc.Move(AdaFruitSSD1306.Width, AdaFruitSSD1306.Height);
                    oled.DrawBitmap(loc.x, loc.y, ref spaceInvader, 16, 16, AdaFruitSSD1306.Color.White);
                }
                oled.Refresh();
            }
        }

        public static void DisplaySquares() {
            var y = AdaFruitSSD1306.Height / 2;
            for (var I = 0; I < 2; I++) {
                var dimension = 1;
                for (; dimension < 32; dimension++) {
                    oled.ClearScreen();
                    var x = 32;
                    oled.DrawRectangle(x - (dimension / 2), y - (dimension / 2), dimension, dimension, AdaFruitSSD1306.Color.White);
                    x += 32;
                    oled.DrawRectangle(x - (dimension / 2), y - (dimension / 2), dimension, dimension, AdaFruitSSD1306.Color.White);
                    x += 32;
                    oled.DrawRectangle(x - (dimension / 2), y - (dimension / 2), dimension, dimension, AdaFruitSSD1306.Color.White);
                    oled.Refresh();
                }
                for (; dimension > 0; dimension--) {
                    oled.ClearScreen();
                    var x = 32;
                    oled.DrawRectangle(x - (dimension / 2), y - (dimension / 2), dimension, dimension, AdaFruitSSD1306.Color.White);
                    x += 32;
                    oled.DrawRectangle(x - (dimension / 2), y - (dimension / 2), dimension, dimension, AdaFruitSSD1306.Color.White);
                    x += 32;
                    oled.DrawRectangle(x - (dimension / 2), y - (dimension / 2), dimension, dimension, AdaFruitSSD1306.Color.White);
                    oled.Refresh();
                }
            }
        }

        public static void DisplayCircles() {
            var y = AdaFruitSSD1306.Height / 2;
            var x = 0;
            var r = 1;
            for (var I = 0; I < 2; I++) {
                for (; r < 31; r++) {
                    oled.ClearScreen();
                    oled.DrawCircle(x + 32, y, r, AdaFruitSSD1306.Color.White);
                    oled.DrawCircle(x + 64, y, r, AdaFruitSSD1306.Color.White);
                    oled.DrawCircle(x + 96, y, r, AdaFruitSSD1306.Color.White);
                    oled.Refresh();
                }
                for (; r > 0; r--) {
                    oled.ClearScreen();
                    oled.DrawCircle(x + 32, y, r, AdaFruitSSD1306.Color.White);
                    oled.DrawCircle(x + 64, y, r, AdaFruitSSD1306.Color.White);
                    oled.DrawCircle(x + 96, y, r, AdaFruitSSD1306.Color.White);
                    oled.Refresh();
                }
            }
        }

        public static void DisplayLines() {
            oled.AutoRefreshScreen = true;
            var x1 = 0;
            for (; x1 < AdaFruitSSD1306.Width; x1++) {
                oled.DrawLine(0, AdaFruitSSD1306.Height - 1, x1, 0, AdaFruitSSD1306.Color.White);
            }
            for (; x1 > 0; x1--) {
                oled.DrawLine(AdaFruitSSD1306.Width - 1, 0, x1, AdaFruitSSD1306.Height - 1, AdaFruitSSD1306.Color.White);
            }
            oled.AutoRefreshScreen = false;
            Thread.Sleep(1000);
        }

        public static void DisplayText() {
            oled.ClearScreen();

            int line = 1;

            oled.DrawString(0, line++, "######################");
            oled.DrawString(0, line++, "   Ada Fruit OLED");
            oled.DrawString(0, line++, "  SSD1306 Display");
            oled.DrawString(0, line++, " & netduino helpers");
            oled.DrawString(0, line++, "   by Fabien Royer");
            oled.DrawString(0, line++, " http://codeplex.com");
            oled.DrawString(0, line++, "######################");
            oled.Refresh();

            Thread.Sleep(1000);
        }

        public static void BlinkTest() {
            for (var I = 0; I < 6; I++) {
                oled.InvertDisplay(true);
                Thread.Sleep(100);
                oled.InvertDisplay(false);
                Thread.Sleep(100);
            }
        }

        public static void DisplayNetduinoBitmap() {
            oled.ClearScreen();
            oled.DrawBitmap(0, 0, ref netduino, 128, 64, AdaFruitSSD1306.Color.White);
            oled.Refresh();
            Thread.Sleep(1000);
        }

        public static byte[] spaceInvader = new byte[32] {
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF,
                0xFF,0xFF
        };

        public static byte[] netduino = new byte[AdaFruitSSD1306.bufferSize] {
                0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
                0xF8, 0xF8, 0xF8, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0xF8, 0xF8,
                0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x0F, 0x07, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xC0, 0x60, 0x60, 0x60,
                0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x60, 0x60, 0x60, 0x60, 0xC0, 0xC0, 0x00, 0x00,
                0x00, 0x60, 0xFC, 0xFC, 0x60, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x60, 0x60, 0x60, 0xC0, 0xFE, 0xFE,
                0x00, 0x00, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE6, 0x00,
                0x00, 0x00, 0xE0, 0xE0, 0xC0, 0x60, 0x60, 0x60, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0xC0, 0xC0,
                0x60, 0x60, 0x60, 0x60, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
                0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x7F, 0x66, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x67, 0x27, 0x00,
                0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x80, 0x00, 0x3F, 0x7B, 0xE0, 0xC0, 0xC0, 0xC0, 0x60, 0xFF, 0xFF,
                0x00, 0x00, 0x1F, 0x7F, 0xE0, 0xC0, 0xC0, 0x40, 0x60, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00,
                0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x7F, 0x60,
                0xC0, 0xC0, 0xC0, 0xC0, 0x60, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
                0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x33, 0x71, 0x61, 0x61, 0x61, 0xE1, 0xC3, 0xC7, 0x86,
                0x00, 0x00, 0x00, 0x00, 0x1E, 0x33, 0x71, 0x61, 0x61, 0x61, 0xE1, 0xC3, 0xC7, 0x86, 0x00, 0x00,
                0x00, 0x00, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x07, 0xFE, 0xF8, 0x00, 0x00,
                0x00, 0x08, 0x0C, 0x04, 0x06, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0x03, 0x01,
                0x61, 0x61, 0x71, 0xDF, 0xDE, 0x80, 0x00, 0x00, 0xFC, 0xFF, 0x03, 0x01, 0x01, 0x01, 0x03, 0x07,
                0xFE, 0xF0, 0x00, 0x00, 0xFC, 0xFE, 0x63, 0x31, 0x31, 0x31, 0x31, 0x63, 0xE7, 0x84, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0E, 0x18, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x1F,
                0x07, 0x00, 0x00, 0x06, 0x0E, 0x18, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x1F, 0x07, 0x00,
                0x00, 0x00, 0x3F, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x1C, 0x0F, 0x03, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x1C, 0x18, 0x30,
                0x30, 0x30, 0x30, 0x18, 0x1F, 0x07, 0x00, 0x00, 0x07, 0x1F, 0x18, 0x30, 0x30, 0x30, 0x38, 0x1C,
                0x0F, 0x01, 0x00, 0x00, 0x07, 0x1F, 0x18, 0x30, 0x30, 0x30, 0x30, 0x18, 0x1F, 0x07, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFC, 0xFC, 0xFC,
                0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0xC0, 0x80,
                0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xC0,
                0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
                0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
                0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
                0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
                0xF8, 0xFC, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
                0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
                0x1F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1C, 0x1C, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
                0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
                0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
                0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
                0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
                0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00
            };
    }
}
